package com.radiant.servlet.guice;

import java.beans.IntrospectionException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.simpledb.AmazonSimpleDB;
import com.amazonaws.services.simpledb.AmazonSimpleDBClient;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;
import com.radiant.data.annotation.PreProcessor;
import com.radiant.data.annotation.PreProcessorImpl;
import com.radiant.data.entity.Activity;
import com.radiant.data.entity.ActivityDAO;
import com.radiant.data.entity.ActivityDAOImpl;
import com.radiant.data.entity.Child;
import com.radiant.data.entity.ChildDAO;
import com.radiant.data.entity.ChildDAOImpl;
import com.radiant.data.entity.Comment;
import com.radiant.data.entity.CommentDAO;
import com.radiant.data.entity.CommentDAOImpl;
import com.radiant.data.entity.DevelopmentTrack;
import com.radiant.data.entity.DevelopmentTrackDAO;
import com.radiant.data.entity.DevelopmentTrackDAOImpl;
import com.radiant.data.entity.Measurement;
import com.radiant.data.entity.MeasurementDAO;
import com.radiant.data.entity.MeasurementDAOImpl;
import com.radiant.data.entity.Milestone;
import com.radiant.data.entity.MilestoneDAO;
import com.radiant.data.entity.MilestoneDAOImpl;
import com.radiant.data.entity.Post;
import com.radiant.data.entity.PostDAO;
import com.radiant.data.entity.PostDAOImpl;
import com.radiant.data.entity.Profile;
import com.radiant.data.entity.ProfileDAO;
import com.radiant.data.entity.ProfileDAOImpl;
import com.radiant.data.entity.User;
import com.radiant.data.entity.UserDAO;
import com.radiant.data.entity.UserDAOImpl;
import com.radiant.service.ActivityFeedService;
import com.radiant.service.ActivityFeedServiceImpl;
import com.radiant.service.MonthlyTrackerService;
import com.radiant.service.MonthlyTrackerServiceImpl;
import com.radiant.service.PhotoService;
import com.radiant.service.PhotoServiceImpl;
import com.radiant.service.PostService;
import com.radiant.service.PostServiceImpl;
import com.radiant.service.UserAuthenticationService;
import com.radiant.service.UserAuthenticationServiceImpl;
import com.radiant.service.UserService;
import com.radiant.service.UserServiceImpl;
import com.radiant.servlet.filters.AuthenticationFilter;
import com.radiant.test.Test;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
import com.sun.jersey.guice.JerseyServletModule;

public  class GuiceConfig extends GuiceServletContextListener {

	
    @Override
    protected Injector getInjector() {
       
    	return Guice.createInjector(new JerseyServletModule() {
        	
            @Override
            protected void configureServlets() {

            	ClientConfiguration cc = new ClientConfiguration();
            	cc.setMaxErrorRetry(10);
                AmazonSimpleDB sdb;
                AmazonS3 s3;
                ActivityFeedService activityFeedService = new ActivityFeedServiceImpl();
                MonthlyTrackerService trackerService = new MonthlyTrackerServiceImpl();
                PostService postService = new PostServiceImpl();
                PhotoService photoService = new PhotoServiceImpl();
                UserAuthenticationService authenticationService = new UserAuthenticationServiceImpl();
                UserService userService = new UserServiceImpl();

                try {
        			sdb = new AmazonSimpleDBClient(new PropertiesCredentials(
        			        GuiceConfig.class.getResourceAsStream("/AwsCredentials.properties")), cc);
        			
        			s3 = new AmazonS3Client(new PropertiesCredentials(
        			        GuiceConfig.class.getResourceAsStream("/AwsCredentials.properties")), cc);
        			
        			PreProcessor preProcessor = new PreProcessorImpl();
        			preProcessor.register(Post.class, PostDAO.class);
        			preProcessor.register(Comment.class, CommentDAO.class);
        			preProcessor.register(Child.class, ChildDAO.class);
        			preProcessor.register(Profile.class, ProfileDAO.class);
        			preProcessor.register(DevelopmentTrack.class, DevelopmentTrackDAO.class);
        			preProcessor.register(User.class, UserDAO.class);
        			preProcessor.register(Activity.class, ActivityDAO.class);
        			preProcessor.register(Measurement.class, MeasurementDAO.class);
        			preProcessor.register(Milestone.class, MilestoneDAO.class);

        			preProcessor.run();
        			
        			bind(AmazonSimpleDB.class).toInstance(sdb);
        			bind(AmazonS3.class).toInstance(s3);
        			
        			bind(PreProcessor.class).toInstance(preProcessor);
        			
        			bind(ChildDAO.class).to(ChildDAOImpl.class);
        			bind(CommentDAO.class).to(CommentDAOImpl.class);
        			bind(DevelopmentTrackDAO.class).to(DevelopmentTrackDAOImpl.class);
        			bind(PostDAO.class).to(PostDAOImpl.class);
        			bind(ProfileDAO.class).to(ProfileDAOImpl.class);
        			bind(UserDAO.class).to(UserDAOImpl.class);
        			bind(ActivityDAO.class).to(ActivityDAOImpl.class);
        			bind(MeasurementDAO.class).to(MeasurementDAOImpl.class);
        			bind(MilestoneDAO.class).to(MilestoneDAOImpl.class);

        			bind(ActivityFeedService.class).to(ActivityFeedServiceImpl.class);
        			bind(UserService.class).to(UserServiceImpl.class);
        			bind(UserAuthenticationService.class).to(UserAuthenticationServiceImpl.class);
        			bind(PhotoService.class).to(PhotoServiceImpl.class);
        			bind(PostService.class).to(PostServiceImpl.class);
        			bind(MonthlyTrackerService.class).to(MonthlyTrackerServiceImpl.class);
        			
        			bind(Test.class);
        			bind(ActivityFeedServiceImpl.class);
        			bind(UserServiceImpl.class);
        			bind(UserAuthenticationServiceImpl.class);
        			bind(PhotoServiceImpl.class);
        			bind(PostServiceImpl.class);
        			bind(MonthlyTrackerServiceImpl.class);

        		} catch (IOException e) {
        			// TODO Auto-generated catch block
        			e.printStackTrace();
        		}
        		List<String> protectedPaths = new ArrayList<String>();
        		protectedPaths.addAll(activityFeedService.getProtectedPaths());
        		protectedPaths.addAll(userService.getProtectedPaths());
        		protectedPaths.addAll(authenticationService.getProtectedPaths());
        		protectedPaths.addAll(postService.getProtectedPaths());
        		protectedPaths.addAll(trackerService.getProtectedPaths());
        		for (String path: protectedPaths) {
        			filter(path).through(AuthenticationFilter.class);
        		}
                serve("/*").with(GuiceContainer.class);
            }
    });
}



}